From: Colin Walters Date: Sun, 6 Apr 2025 21:24:26 +0000 (-0400) Subject: sysroot: Detect early on when /boot is on vfat X-Git-Tag: archive/raspbian/2025.7-2+rpi1^2^2~6^2~4^2~34^2 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/www.github.com/%22bookmarks:///%22http:/www.example.com/cgi/%22https:/www.github.com/%22bookmarks:/?a=commitdiff_plain;h=cbce703cf7fca2a83911e12063554d9f2b0757b9;p=ostree.git sysroot: Detect early on when /boot is on vfat We do want to support this (as part of supporing the Boot Loader Spec) but because we use symlinks in `/boot`, can't yet. Error out very early on consistently if we detect vfat for /boot, but also add a member variable to keep track of this in preparation for supporting it. Signed-off-by: Colin Walters --- diff --git a/src/libostree/ostree-sysroot-deploy.c b/src/libostree/ostree-sysroot-deploy.c index 49168d4f..6803d1d0 100644 --- a/src/libostree/ostree-sysroot-deploy.c +++ b/src/libostree/ostree-sysroot-deploy.c @@ -2216,8 +2216,9 @@ swap_bootloader (OstreeSysroot *sysroot, OstreeBootloader *bootloader, int curre if (!_ostree_sysroot_ensure_boot_fd (sysroot, error)) return FALSE; - g_assert_cmpint (sysroot->boot_fd, !=, -1); + // We use symlinks here. + g_assert (!sysroot->boot_is_vfat); /* The symlink was already written, and we used syncfs() to ensure * its data is in place. Renaming now should give us atomic semantics; diff --git a/src/libostree/ostree-sysroot-private.h b/src/libostree/ostree-sysroot-private.h index ac5d271c..9a6566d5 100644 --- a/src/libostree/ostree-sysroot-private.h +++ b/src/libostree/ostree-sysroot-private.h @@ -70,6 +70,9 @@ struct OstreeSysroot // File descriptor for the boot partition. Should be initialized on demand internally // by a public API eventually invoking `_ostree_sysroot_ensure_boot_fd()`. int boot_fd; + // Set if the /boot filesystem is VFAT. + // Only initialized if boot_fd is set. + gboolean boot_is_vfat; // Lock for this sysroot. GLnxLockFile lock; diff --git a/src/libostree/ostree-sysroot.c b/src/libostree/ostree-sysroot.c index 3e237c39..e45a71f6 100644 --- a/src/libostree/ostree-sysroot.c +++ b/src/libostree/ostree-sysroot.c @@ -22,8 +22,10 @@ #include "otutil.h" #include +#include #include #include +#include #include #include "ostree-bootloader-aboot.h" @@ -338,6 +340,19 @@ ensure_sysroot_fd (OstreeSysroot *self, GError **error) return TRUE; } +static gboolean +validate_boot_fd (OstreeSysroot *self, int fd, GError **error) +{ + g_assert_cmpint (fd, !=, -1); + struct statfs stbuf; + if (fstatfs (fd, &stbuf) < 0) + return glnx_throw_errno_prefix (error, "fstatfs(boot)"); + self->boot_is_vfat = (stbuf.f_type == MSDOS_SUPER_MAGIC); + if (self->boot_is_vfat) + return glnx_throw (error, "/boot cannot currently be a vfat filesystem"); + return TRUE; +} + /* Require that both self->sysroot_fd is set. * If the sysroot has a boot/ subdirectory, it will be loaded. * If not, self->boot_fd will remain -1. @@ -352,14 +367,18 @@ _ostree_sysroot_maybe_load_boot_fd (OstreeSysroot *self, GError **error) return FALSE; if (self->boot_fd == -1) { - int fd = glnx_opendirat_with_errno (self->sysroot_fd, "boot", TRUE); + glnx_autofd int fd = glnx_opendirat_with_errno (self->sysroot_fd, "boot", TRUE); if (fd < 0) { if (errno != ENOENT) return glnx_throw_errno_prefix (error, "Opening boot/"); } else - self->boot_fd = fd; + { + if (!validate_boot_fd (self, fd, error)) + return FALSE; + self->boot_fd = glnx_steal_fd (&fd); + } } return TRUE; } @@ -372,8 +391,12 @@ _ostree_sysroot_ensure_boot_fd (OstreeSysroot *self, GError **error) return FALSE; if (self->boot_fd == -1) { - if (!glnx_opendirat (self->sysroot_fd, "boot", TRUE, &self->boot_fd, error)) + glnx_autofd int fd = -1; + if (!glnx_opendirat (self->sysroot_fd, "boot", TRUE, &fd, error)) + return FALSE; + if (!validate_boot_fd (self, fd, error)) return FALSE; + self->boot_fd = glnx_steal_fd (&fd); } return TRUE; } diff --git a/tests/kolainst/nondestructive/itest-alt-sysroot.sh b/tests/kolainst/nondestructive/itest-alt-sysroot.sh new file mode 100755 index 00000000..eb6af64d --- /dev/null +++ b/tests/kolainst/nondestructive/itest-alt-sysroot.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Run test-basic.sh as root. +# https://github.com/ostreedev/ostree/pull/1199 + +set -xeuo pipefail + +if test $(readlink /proc/1/ns/mnt) = $(readlink /proc/self/ns/mnt); then + exec unshare -m -- "$0" "$@" +fi + +. ${KOLA_EXT_DATA}/libinsttest.sh + +# Use /var/tmp to hopefully use XFS + O_TMPFILE etc. +prepare_tmpdir /var/tmp +trap _tmpdir_cleanup EXIT + +truncate -s 512M boot.img +mkfs.vfat boot.img + +mkdir sysroot +ostree admin init-fs -E 1 sysroot +mount -o loop boot.img sysroot/boot +if ostree admin status --sysroot=sysroot 2>err.txt; then + # So cleanup works on failure too + umount sysroot/boot + fatal "computed status on vfat sysroot" +fi +umount sysroot/boot +assert_file_has_content_literal err.txt "/boot cannot currently be a vfat filesystem"